import 'dart:convert';
import 'dart:io';

import 'package:simple_server/src/json.dart';
import 'package:simple_server/src/log.dart';

class BaseContext {
  final JsonMap _data = {};

  dynamic operator [](String key) {
    final value = _data[key];
    if (value != null) return value;
    final json = _data['json'];
    if (json is Map) {
      final jsonValue = json[key];
      if (jsonValue != null) return jsonValue;
    }
    return null;
  }

  void operator []=(String key, dynamic value) => _data[key] = value;

  dynamic value(String key) => _data[key];

  void remove(String key) => _data.remove(key);

  bool get hasData => _data.isNotEmpty;

  void _log(Object? object) {
    if (object is String) {
      log('resp: $object');
    } else {
      log('resp: ${jsonPretty(object)}');
    }
  }

  void write(Object? object) => _log(object);

  void writeln([Object? object = ""]) => _log(object);

  set statusCode(int code) => log('statusCode: $code');

  void json(dynamic data) => write(jsonEncode(data));

  bool get auth => _data['auth'] ?? false;

  set auth(bool value) => _data['auth'] = value;

  bool get noErrorResp => _data['noErrorResp'] ?? false;

  set noErrorResp(bool value) => _data['noErrorResp'] = value;

  void ok() => statusCode = HttpStatus.ok;

  void noContent() => statusCode = HttpStatus.noContent;

  void writeErrorMessage([String? message]) {
    if (message == null || noErrorResp) return;
    write(message);
  }

  void unauthorized([String? message]) {
    statusCode = HttpStatus.unauthorized;
    writeErrorMessage(message);
  }

  void notFound([String? message]) {
    statusCode = HttpStatus.notFound;
    writeErrorMessage(message);
  }

  void badRequest([String? message]) {
    statusCode = HttpStatus.badRequest;
    writeErrorMessage(message);
  }

  void internalServerError([String? message]) {
    statusCode = HttpStatus.internalServerError;
    writeErrorMessage(message);
  }

  void forbidden([String? message]) {
    statusCode = HttpStatus.forbidden;
    writeErrorMessage(message);
  }

  JsonMap toJson() {
    final temp = {..._data};
    final auth = temp.remove('auth') ?? false;
    return {
      'auth': auth,
      if (temp.isNotEmpty) 'data': temp,
    };
  }

  @override
  String toString() => jsonPretty(toJson());

  String toLimitString([int length = 100]) {
    final str = toString();
    return str.length <= length ? str : str.substring(0, length);
  }
}
